<template>
  <div class="chat" :style="{ height: innerH + 'px' }">
    <div class="chatContainer" :style="{ height: innerH1 + 'px' }">
      <div class="chatBoxBox">
        <transition name="fadeIn">
          <div class="chatItem" v-if="chatItem.length !== 0">
            <chatBox v-for="(item, index) in chatItem" :chatInfo="item" :key="index"></chatBox>
          </div>
        </transition>
      </div>
      <div class="pc">
        <Textarea v-model="content" height="130px" :placeholder="ifLogin ? '欢迎聊天...' : '请先登录'" :disabled="!ifLogin"></Textarea>
        <Button class="pc-button" @click="sendMessage" :disabled="!ifLogin">发消息</Button>
      </div>

      <div class="mv">
        <input :disabled="!ifLogin" type="text" v-model="content" />

        <Button @click="sendMessage" :disabled="!ifLogin">发消息</Button>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import chatBox from '../../components/chatBox.vue'
import Bus from '../../bus'
import $axios from '@/http'
import Textarea from '@/components/Textarea/index.vue'
import { ref, onMounted, computed, onBeforeUnmount } from 'vue'
import { useStore } from 'vuex'
import { socketURL } from '@/http'
import msg from '@/components/msg/msg'
import Button from '@/components/button.vue'

type TChatRoomType = {
  type: 'chat' | 'notic' | 'heart'
  message: string
}
const $store = useStore()
const connectStatus = ref<boolean>(true)
const content = ref<string>('')
const chatItem = ref<Array<any>>([]) //所有谈话内容
const heartCheckTime = ref<number | null>(null)
const ws = ref<WebSocket | null>(null)
const reConnectTime = ref<number>(0)
onMounted(() => {
  initContent()
  if (ifLogin.value) {
    initJoinRoom()
    tokeContent()
  }
})
onBeforeUnmount(() => {
  connectStatus.value = false
  heartCheckTime.value && clearInterval(heartCheckTime.value)
  ws.value?.close()
  ws.value = null
})
const innerH = computed(() => (document.body.clientWidth < 765 ? window.innerHeight - 63 : false))
// 移动端浏览器要额外适配 通过window.innerHeight
const innerH1 = computed(() => (document.body.clientWidth < 765 ? window.innerHeight - 103 : false))
const ifLogin = computed(() => $store.getters.user.username)

const initContent = () => {
  $axios
    .get('/chatRoom/search')
    .then((res) => {
      if (res.data.error === -1) {
        chatItem.value = res.data.data
        const chartBoxDom: HTMLElement | null = document.querySelector('.chatBoxBox')
        setTimeout(() => {
          chartBoxDom && (chartBoxDom.scrollTop = chartBoxDom.scrollHeight)
        })
      } else {
        // 错误提示
        chatItem.value = []
      }
    })
    .catch((err) => {
      Bus.$emit('live2dAboutSendError')
    })
}
const reConnect = () => {
  reConnectTime.value++
  initJoinRoom()
  tokeContent()
}
//正在谈话
const tokeContent = () => {
  if (!ws.value) {
    return
  }
  ws.value.onclose = () => {
    // if (connectStatus.value) {
    // msg.error("断开链接, 重连中。。。");
    // reConnect();
    // }
  }
  ws.value.onerror = () => {
    if (reConnectTime.value >= 10) {
      msg.error('与聊天室断开连接！')
      return
    }
    msg.error('连接错误。。。正在尝试重新链接')
    setTimeout(() => {
      reConnect()
    }, 3500)
  }
  ws.value.onmessage = ({ data }) => {
    const message = JSON.parse(data)
    chatItem.value.push(message)
    const chartBoxDom: HTMLElement | null = document.querySelector('.chatBoxBox')
    setTimeout(() => {
      chartBoxDom!.scrollTop = chartBoxDom!.scrollHeight
    })
  }
}
// 初始化加入房间 即管理员进入指定房间,其他人进入随机房间
const initJoinRoom = () => {
  if ($store.getters.user.id) {
    ws.value = new WebSocket(`${socketURL}/socketRoom/${$store.getters.user.id}`)
  }
  ws.value &&
    (ws.value.onopen = () => {
      if (reConnectTime.value === 0) {
        msg.success(`欢迎${$store.getters.user.realname}进入房间`)
      } else {
        msg.success('重连成功')
        initContent()
      }
      reConnectTime.value = 0
    })
  if (heartCheckTime.value) {
    clearInterval(heartCheckTime.value)
  }
  // 心跳检测
  heartCheckTime.value = setInterval(() => {
    heartCheck()
  }, 40000)
}
const sendMessage = () => {
  startSendMessage()
}
const startSendMessage = (type: TChatRoomType = { type: 'chat', message: '' }) => {
  if (!content.value.trim() || !ws.value) {
    return
  }
  const sendMessage = {
    message: type.message || content.value,
    userId: $store.getters.user.id,
    type: type.type,
    realname: $store.getters.user.realname,
    avatar: $store.getters.user.avatar
  }
  ws.value?.send(JSON.stringify(sendMessage))
  content.value = ''
}
const heartCheck = () => {
  const sendMessage = {
    userId: $store.getters.user.id,
    type: 'heart'
  }
  ws.value?.send(JSON.stringify(sendMessage))
}
</script>

<style lang="scss" scoped>
// @import url("../../css/mobile/mvsocket.scss");
@import '../../css/pc/socket.scss';
</style>
